/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package jtmcraft.graphics;

import java.awt.Color;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.awt.image.ImageProducer;
import java.awt.image.RGBImageFilter;
import java.io.IOException;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;

/**
 *
 * @author tom
 */
public class ImageResourceFactory {

    public enum eImageResource {

        //sekwencje
        eSwordstanShieldMoveE("walking e00", "bmp", "/jtmcraft/resource/images/swordstan_shield_walking/", 8, new Color(106, 76, 48), new int[]{18, 18}, new int[]{60, 65}, 50),
        eSwordstanShieldMoveN("walking n00", "bmp", "/jtmcraft/resource/images/swordstan_shield_walking/", 8, new Color(106, 76, 48), new int[]{18, 18}, new int[]{60, 65}, 50),
        eSwordstanShieldMoveNE("walking ne00", "bmp", "/jtmcraft/resource/images/swordstan_shield_walking/", 8, new Color(106, 76, 48), new int[]{18, 18}, new int[]{60, 65}, 50),
        eSwordstanShieldMoveNW("walking nw00", "bmp", "/jtmcraft/resource/images/swordstan_shield_walking/", 8, new Color(106, 76, 48), new int[]{18, 18}, new int[]{60, 65}, 50),
        eSwordstanShieldMoveS("walking s00", "bmp", "/jtmcraft/resource/images/swordstan_shield_walking/", 8, new Color(106, 76, 48), new int[]{18, 18}, new int[]{60, 65}, 50),
        eSwordstanShieldMoveSE("walking se00", "bmp", "/jtmcraft/resource/images/swordstan_shield_walking/", 8, new Color(106, 76, 48), new int[]{18, 18}, new int[]{60, 65}, 50),
        eSwordstanShieldMoveSW("walking sw00", "bmp", "/jtmcraft/resource/images/swordstan_shield_walking/", 8, new Color(106, 76, 48), new int[]{18, 18}, new int[]{60, 65}, 50),
        eSwordstanShieldMoveW("walking w00", "bmp", "/jtmcraft/resource/images/swordstan_shield_walking/", 8, new Color(106, 76, 48), new int[]{18, 18}, new int[]{60, 65}, 50),
        eSwordstanShieldAttackE("attack e00", "bmp", "/jtmcraft/resource/images/swordstan_shield_attack/", 13, new Color(106, 76, 48), new int[]{18, 18}, new int[]{60, 65}, 50),
        eSwordstanShieldAttackN("attack n00", "bmp", "/jtmcraft/resource/images/swordstan_shield_attack/", 13, new Color(106, 76, 48), new int[]{18, 18}, new int[]{60, 65}, 50),
        eSwordstanShieldAttackNE("attack ne00", "bmp", "/jtmcraft/resource/images/swordstan_shield_attack/", 13, new Color(106, 76, 48), new int[]{18, 18}, new int[]{60, 65}, 50),
        eSwordstanShieldAttackNW("attack nw00", "bmp", "/jtmcraft/resource/images/swordstan_shield_attack/", 13, new Color(106, 76, 48), new int[]{18, 18}, new int[]{60, 65}, 50),
        eSwordstanShieldAttackS("attack s00", "bmp", "/jtmcraft/resource/images/swordstan_shield_attack//", 13, new Color(106, 76, 48), new int[]{18, 18}, new int[]{60, 65}, 50),
        eSwordstanShieldAttackSE("attack se00", "bmp", "/jtmcraft/resource/images/swordstan_shield_attack/", 13, new Color(106, 76, 48), new int[]{18, 18}, new int[]{60, 65}, 50),
        eSwordstanShieldAttackSW("attack sw00", "bmp", "/jtmcraft/resource/images/swordstan_shield_attack/", 13, new Color(106, 76, 48), new int[]{18, 18}, new int[]{60, 65}, 50),
        eSwordstanShieldAttackW("attack w00", "bmp", "/jtmcraft/resource/images/swordstan_shield_attack/", 13, new Color(106, 76, 48), new int[]{18, 18}, new int[]{60, 65}, 50),

        eCarrierMoveE("walking e00", "bmp", "/jtmcraft/resource/images/carrier_basic_walking/", 8, new Color(97,68,43), new int[]{18, 18}, new int[]{60, 65}, 50),
        eCarrierMoveN("walking n00", "bmp", "/jtmcraft/resource/images/carrier_basic_walking/", 8, new Color(97,68,43), new int[]{18, 18}, new int[]{60, 65}, 50),
        eCarrierMoveNE("walking ne00", "bmp", "/jtmcraft/resource/images/carrier_basic_walking/", 8, new Color(97,68,43), new int[]{18, 18}, new int[]{60, 65}, 50),
        eCarrierMoveNW("walking nw00", "bmp", "/jtmcraft/resource/images/carrier_basic_walking/", 8, new Color(97,68,43), new int[]{18, 18}, new int[]{60, 65}, 50),
        eCarrierMoveS("walking s00", "bmp", "/jtmcraft/resource/images/carrier_basic_walking/", 8, new Color(97,68,43), new int[]{18, 18}, new int[]{60, 65}, 50),
        eCarrierMoveSE("walking se00", "bmp", "/jtmcraft/resource/images/carrier_basic_walking/", 8, new Color(97,68,43), new int[]{18, 18}, new int[]{60, 65}, 50),
        eCarrierMoveSW("walking sw00", "bmp", "/jtmcraft/resource/images/carrier_basic_walking/", 8, new Color(97,68,43), new int[]{18, 18}, new int[]{60, 65}, 50),
        eCarrierMoveW("walking w00", "bmp", "/jtmcraft/resource/images/carrier_basic_walking/", 8, new Color(97,68,43), new int[]{18, 18}, new int[]{60, 65}, 50),

        eCarrierGoldMoveE("walking e00", "bmp", "/jtmcraft/resource/images/carrier_gold_walking/", 8, new Color(97,68,43), new int[]{18, 18}, new int[]{60, 65}, 50),
        eCarrierGoldMoveN("walking n00", "bmp", "/jtmcraft/resource/images/carrier_gold_walking/", 8, new Color(97,68,43), new int[]{18, 18}, new int[]{60, 65}, 50),
        eCarrierGoldMoveNE("walking ne00", "bmp", "/jtmcraft/resource/images/carrier_gold_walking/", 8, new Color(97,68,43), new int[]{18, 18}, new int[]{60, 65}, 50),
        eCarrierGoldMoveNW("walking nw00", "bmp", "/jtmcraft/resource/images/carrier_gold_walking/", 8, new Color(97,68,43), new int[]{18, 18}, new int[]{60, 65}, 50),
        eCarrierGoldMoveS("walking s00", "bmp", "/jtmcraft/resource/images/carrier_gold_walking/", 8, new Color(97,68,43), new int[]{18, 18}, new int[]{60, 65}, 50),
        eCarrierGoldMoveSE("walking se00", "bmp", "/jtmcraft/resource/images/carrier_gold_walking/", 8, new Color(97,68,43), new int[]{18, 18}, new int[]{60, 65}, 50),
        eCarrierGoldMoveSW("walking sw00", "bmp", "/jtmcraft/resource/images/carrier_gold_walking/", 8, new Color(97,68,43), new int[]{18, 18}, new int[]{60, 65}, 50),
        eCarrierGoldMoveW("walking w00", "bmp", "/jtmcraft/resource/images/carrier_gold_walking/", 8, new Color(97,68,43), new int[]{18, 18}, new int[]{60, 65}, 50),

        //budynki
        eBuildingMine( "mine", "bmp", "/jtmcraft/resource/images/buildings/", 1, new Color(191,123,199), new int[]{0,0}, new int[]{60,108},100 ),
        eBuildingStorehouse( "storehouse", "bmp", "/jtmcraft/resource/images/buildings/", 1, new Color(179, 103, 183), new int[]{0,0}, new int[]{255,384},50 ),

        //srodowisko
        //0
        eEnvironmetEarthTile("earth_light_ground", "bmp", "/jtmcraft/resource/images/environment_earth_tiles/", new int[]{0,0}, new int[]{128,96},100),
        eEnvironmetGrass("grass", "bmp", "/jtmcraft/resource/images/environment_earth_tiles/", new int[]{0,0}, new int[]{128,96},100),
        //2
        eEnvironmetEartGrass_1_1("env_1_1", "bmp", "/jtmcraft/resource/images/environment_earth_tiles/", new Color(191,123,199), new int[]{0,0}, new int[]{128,96},100),
        eEnvironmetEartGrass_1_2("env_1_2", "bmp", "/jtmcraft/resource/images/environment_earth_tiles/", new Color(191,123,199), new int[]{0,0}, new int[]{128,96},100),
        eEnvironmetEartGrass_1_3("env_1_3", "bmp", "/jtmcraft/resource/images/environment_earth_tiles/", new Color(191,123,199), new int[]{0,0}, new int[]{128,96},100),
        //5
        eEnvironmetEartGrass_1_4("env_1_4", "bmp", "/jtmcraft/resource/images/environment_earth_tiles/", new Color(191,123,199), new int[]{0,0}, new int[]{128,96},100),
        eEnvironmetEartGrass_2_1("env_2_1", "bmp", "/jtmcraft/resource/images/environment_earth_tiles/", new Color(191,123,199), new int[]{0,0}, new int[]{128,96},100),
        eEnvironmetEartGrass_2_2("env_2_2", "bmp", "/jtmcraft/resource/images/environment_earth_tiles/", new Color(191,123,199), new int[]{0,0}, new int[]{128,96},100),
        eEnvironmetEartGrass_2_3("env_2_3", "bmp", "/jtmcraft/resource/images/environment_earth_tiles/", new Color(191,123,199), new int[]{0,0}, new int[]{128,96},100),
        eEnvironmetEartGrass_2_4("env_2_4", "bmp", "/jtmcraft/resource/images/environment_earth_tiles/", new Color(191,123,199), new int[]{0,0}, new int[]{128,96},100),
        //10
        eEnvironmetEartGrass_4_1("env_4_1", "bmp", "/jtmcraft/resource/images/environment_earth_tiles/", new Color(191,123,199), new int[]{0,0}, new int[]{128,96},100),
        eEnvironmetEartGrass_4_2("env_4_2", "bmp", "/jtmcraft/resource/images/environment_earth_tiles/", new Color(191,123,199), new int[]{0,0}, new int[]{128,96},100),
        eEnvironmetEartGrass_4_3("env_4_3", "bmp", "/jtmcraft/resource/images/environment_earth_tiles/", new Color(191,123,199), new int[]{0,0}, new int[]{128,96},100),
        eEnvironmetEartGrass_4_4("env_4_4", "bmp", "/jtmcraft/resource/images/environment_earth_tiles/", new Color(191,123,199), new int[]{0,0}, new int[]{128,96},100),
        eEnvironmetEartGrass_5_1("env_5_1", "bmp", "/jtmcraft/resource/images/environment_earth_tiles/", new Color(191,123,199), new int[]{0,0}, new int[]{128,96},100),
        //15
        eEnvironmetEartGrass_5_2("env_5_2", "bmp", "/jtmcraft/resource/images/environment_earth_tiles/", new Color(191,123,199), new int[]{0,0}, new int[]{128,96},100),
        eEnvironmetEartGrass_5_3("env_5_3", "bmp", "/jtmcraft/resource/images/environment_earth_tiles/", new Color(191,123,199), new int[]{0,0}, new int[]{128,96},100),
        eEnvironmetEartGrass_5_4("env_5_4", "bmp", "/jtmcraft/resource/images/environment_earth_tiles/", new Color(191,123,199), new int[]{0,0}, new int[]{128,96},100),
        eEnvironmetEartGrass_6_1("env_6_1", "bmp", "/jtmcraft/resource/images/environment_earth_tiles/", new Color(191,123,199), new int[]{0,0}, new int[]{128,96},100),
        eEnvironmetEartGrass_6_2("env_6_2", "bmp", "/jtmcraft/resource/images/environment_earth_tiles/", new Color(191,123,199), new int[]{0,0}, new int[]{128,96},100),
        //20
        eEnvironmetEartGrass_6_3("env_6_3", "bmp", "/jtmcraft/resource/images/environment_earth_tiles/", new Color(191,123,199), new int[]{0,0}, new int[]{128,96},100),
        eEnvironmetEartGrass_6_4("env_6_4", "bmp", "/jtmcraft/resource/images/environment_earth_tiles/", new Color(191,123,199), new int[]{0,0}, new int[]{128,96},100),

        //przyciski
        eNewCarrierNormal("normal", "bmp", "/jtmcraft/resource/images/button/new_carrier/",1, new Color(97,68,43), new int[]{0, 0}, new int[]{75, 75}, 75 ),
        eNewCarrierMouseOver("moveover", "bmp", "/jtmcraft/resource/images/button/new_carrier/",1, new Color(97,68,43), new int[]{0, 0}, new int[]{75, 75}, 75 ),
        eNewCarrierPush("push", "bmp", "/jtmcraft/resource/images/button/new_carrier/",1, new Color(97,68,43), new int[]{0, 0}, new int[]{75, 75}, 75 ),
        ;
        private String fileName;
        private String fileExtention;
        private String directory;
        private int countSequence;
        private Color transparentColor;
        private int[] activeTopLeftPoint;
        private int[] activeWidthHeight;
        private int preferredPercentSize;

        private eImageResource(String fileName, String fileExtention, String directory, int countSequence,
                Color transparentColor, int[] activeTopLeftPoint, int[] activeWidthHeight, int preferredPercentSize) {
            this.fileName = fileName;
            this.fileExtention = fileExtention;
            this.directory = directory;
            this.countSequence = countSequence;
            this.transparentColor = transparentColor;
            this.activeTopLeftPoint = activeTopLeftPoint;
            this.activeWidthHeight = activeWidthHeight;
            this.preferredPercentSize = preferredPercentSize;
        }

        private eImageResource(String fileName, String fileExtention, String directory, Color transparentColor,
                int[] activeTopLeftPoint, int[] activeWidthHeight, int preferredPercentSize) {
            this(fileName, fileExtention, directory, 0, transparentColor, activeTopLeftPoint,
                    activeWidthHeight, preferredPercentSize);
        }

        private eImageResource(String fileName, String fileExtention, String directory,
                int[] activeTopLeftPoint, int[] activeWidthHeight, int preferredPercentSize) {
            this(fileName, fileExtention, directory, 0, null, activeTopLeftPoint,
                    activeWidthHeight, preferredPercentSize);
        }

        public int getCountSequence() {
            return countSequence;
        }

        public String getDirectory() {
            return directory;
        }

        public String getFileExtention() {
            return fileExtention;
        }

        public String getFileName() {
            return fileName;
        }

        public Color getTransparentColor() {
            return transparentColor;
        }

        public int[] getActiveTopLeftPointt() {
            return activeTopLeftPoint;
        }

        public int[] getActiveWidthHeight() {
            return activeWidthHeight;
        }

        public int getPreferredPercentSize() {
            return preferredPercentSize;
        }
        
    }
    private HashMap<String, Image[]> imageSequenceMap = new HashMap<String, Image[]>();
    private HashMap<String, Image> imageMap = new HashMap<String, Image>();
    private static ImageResourceFactory instance;

    public static ImageResourceFactory getInstance() {
        if (instance == null) {
            instance = new ImageResourceFactory();
        }

        return instance;
    }

    private ImageResourceFactory() {
    }

    public Image[] getImageSequence(ImageResourceFactory.eImageResource imageResource) {
        String key = imageResource.getDirectory() + "/" + imageResource.fileName;
        if (imageSequenceMap.containsKey( key )) {
            return imageSequenceMap.get(key);
        }

        Image[] images = createImageSequence(imageResource);
        imageSequenceMap.put(key, images);
        return images;

    }

    public Image getImage(ImageResourceFactory.eImageResource imageResource) {
        String key = imageResource.getDirectory() + "/" + imageResource.fileName;

        if (imageResource.getCountSequence() > 0) {
            return getImageSequence(imageResource)[0];
        }

        if (imageMap.containsKey(key)) {
            return imageMap.get(key);
        }

        String filePath = imageResource.getDirectory() + imageResource.fileName + "." + imageResource.getFileExtention();
        Image image = null;
        try {
            image = readAndTransformImage(filePath, imageResource);
            imageMap.put(key, image);
        } catch (IOException ex) {
            Logger.getLogger(ImageResourceFactory.class.getName()).log(Level.SEVERE, null, ex);
        }

        return image;
    }

    private Image readAndTransformImage(String filePath, eImageResource imageResource) throws IOException {
        BufferedImage srcImage = ImageIO.read(getClass().getResourceAsStream(filePath));
        srcImage = srcImage.getSubimage(imageResource.getActiveTopLeftPointt()[0], imageResource.getActiveTopLeftPointt()[1],
                imageResource.getActiveWidthHeight()[0],
                imageResource.getActiveWidthHeight()[1]);
        Image tmpImage = srcImage;
        if( imageResource.getTransparentColor() != null )
        {
            tmpImage = makeTransparentImage(srcImage, imageResource.getTransparentColor());
        }
        //wytwarzamy grafike zgodna z urzadzeniem
        GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
        //BufferedImage dstImage = gc.createCompatibleImage(tmpImage.getWidth(null), tmpImage.getHeight(null), Transparency.BITMASK);
        BufferedImage dstImage = gc.createCompatibleImage((int) (imageResource.getActiveWidthHeight()[0] / (100 / imageResource.getPreferredPercentSize())),
                (int) (imageResource.getActiveWidthHeight()[1] / (100 / imageResource.getPreferredPercentSize())),
                Transparency.BITMASK);
        dstImage.createGraphics().drawImage(tmpImage, 0, 0,
                imageResource.getActiveWidthHeight()[0] / (100 / imageResource.getPreferredPercentSize()),
                imageResource.getActiveWidthHeight()[1] / (100 / imageResource.getPreferredPercentSize()),
                null);
        //Graphics2D gd2 = dstImage.createGraphics();
        /*
        dstImage.createGraphics().drawImage(tmpImage, 0, 0,
        imageResource.getActiveTopLeftPointt()[0],
        imageResource.getActiveTopLeftPointt()[1],
        imageResource.getActiveTopLeftPointt()[0], imageResource.getActiveTopLeftPointt()[1],
        imageResource.getActiveWidthHeight()[0] - imageResource.getActiveTopLeftPointt()[0],
        imageResource.getActiveWidthHeight()[1] - imageResource.getActiveTopLeftPointt()[1],
        null);

         */
        /*
        dstImage.createGraphics().drawImage(tmpImage, 0, 0, //-imageResource.getActiveTopLeftPointt()[0], -imageResource.getActiveTopLeftPointt()[1],
        imageResource.getActiveWidthHeight()[0] - imageResource.getActiveTopLeftPointt()[0],
        imageResource.getActiveWidthHeight()[1] - imageResource.getActiveTopLeftPointt()[1],
        null);
         */
        return dstImage;
    }

    private Image[] createImageSequence(ImageResourceFactory.eImageResource imageResource) {

        Image[] images = new Image[imageResource.getCountSequence()];
        for (int i = 0; i < imageResource.getCountSequence(); ++i) {
            String filePath = imageResource.getDirectory() + imageResource.fileName;
            if (i < 10) {
                filePath += "0";
            }
            filePath += i + "." + imageResource.getFileExtention();
            try {
                images[i] = readAndTransformImage(filePath, imageResource);
            } catch (IOException ex) {
                Logger.getLogger(ImageResourceFactory.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

        return images;
    }

    private Image makeTransparentImage(BufferedImage im, final Color transparentColor) {
        ImageFilter filter = new RGBImageFilter() {

            //kolor z kanalem alfa
            public int markerRGB = transparentColor.getRGB() | 0xFF000000;

            //filtr do przeksztalcenia grafiki w transparentna
            public final int filterRGB(int x, int y, int rgb) {
                if ((rgb | 0xFF000000) == markerRGB) {
                    // Mark the alpha bits as zero - transparent
                    return 0x00FFFFFF & rgb;
                } else {
                    // nothing to do
                    return rgb;
                }
            }
        };

        //dopinamy filtr
        ImageProducer ip = new FilteredImageSource(im.getSource(), filter);
        return Toolkit.getDefaultToolkit().createImage(ip);
    }
    
    public void loadImages( )
    {
        eImageResource[] values = eImageResource.values();
        for( eImageResource imageResource : values )
        {
            getImage( imageResource );
        }
    }
    
}
